import { DeviceEventEmitter, NativeModules } from "react-native";
import XLog from "./XLog";
import {RS_Device_Type, Max_Timeout_Count, Recv_Error_Def} from "./SerialCommon";
const { SerialPortAPI } = NativeModules;
import SerialController4Client from "./SerialController4Client";
import SerialController6Client from "./SerialController6Client";
import SerialMeterClient from "./SerialMeterClient";

class SerialPortClient {
    constructor(options, clientRef, index, type, address, id) {
		this.options = options;
		this.type = type;
		this.id = id;
		this.clientRef = clientRef;
		this.index = index;
		this.eventHandler = {};
		this.deviceHandler = this.getDeviceHandler(type, address, index, id);
		this.sendTimer = null;
		this.sendInterval = 4000;
		this.requestList = [];
		this.timeoutCount = 0;

		// 接收处理函数，接收到的字节会按照协议去分析，若能组成一条指令，则按指令去解析，然后清除掉定时器，并调用realSend继续发送
		// 若不能组成指令，则返回错误，目前的错误主要包括：起始码错误、长度不足错误、校验和错误和设备地址错误
		this.dispatchEvent = function(event) {
			if(event && event.key == this.clientRef) {
				const {data, type} = event;
				if(type == "receive"){
					if(this.deviceHandler && this.deviceHandler.handleReceiveMessage){
						let ret = this.deviceHandler.handleReceiveMessage(data);
						if(ret && ret.error){
							XLog.e("handleReceiveMessage error:", data, ret);
							return;
						}
						if(ret && ret.type && this.eventHandler[ret.type]){
							this.eventHandler[ret.type](ret);
						}
					}
					clearTimeout(this.sendTimer);
					this.sendTimer = null;
					this.realSend();
				} else if(this.eventHandler[type]) {
					this.eventHandler[type](data);
				}			
			}	
		}
	}

	on(event, callback){
		this.eventHandler[event] = callback;
	}

	getDeviceHandler(type, address, index, id){
		switch(type){
			case RS_Device_Type.LOOP_4WAY:
				return new SerialController4Client(address, index, id);
			
			case RS_Device_Type.LOOP_6WAY:
				return new SerialController6Client(address, index, id);

			case RS_Device_Type.METER:
				return new SerialMeterClient(address, index, id);

			default:
				return null;
		}
	}

    send(message) {
		console.log("send: ", message);
		return SerialPortAPI.send(this.clientRef, message).catch(error=>{
			XLog.e(`[${this.clientRef}]send error:`,error?.message);
		});
    }

    close(isForce) {
        return SerialPortAPI.close(this.clientRef, isForce).catch(error=>{
			XLog.e(`[${this.clientRef}]close error:`,error?.message);
		});
    }

	// 超时处理函数，如连续超时达到一定次数，向后端报告超时事件
	timeoutHandler(timeoutFlag){
		if(!timeoutFlag){
			this.timeoutCount = 0;
			return;
		}
		this.timeoutCount++;
		if(this.timeoutCount >= Max_Timeout_Count){
			this.eventHandler["timeout"]({key: this.clientRef, 
										  event: "timeout", 
										  index: this.index,
										  id: this.id });
			this.timeoutCount = 0;
		}
	}

	// 发送指令函数，参数为True表示是超时触发调用的，这时会进入超时处理逻辑
	// 每次发送一条指令时，会启动定时器，等待设备回复，若超时未回复，则调用realSend(true)
	realSend(timeoutFlag = false){
		if(this.requestList == null || this.requestList.length == 0 || this.sendTimer != null){
			return;
		}
		this.sendTimer = setTimeout(()=>{
			console.log("realSend timeout eval " + new Date().getTime(), this.sendTimer, timeoutFlag, this.index);
			this.sendTimer = null;
			this.realSend(true);
		}, this.sendInterval);

		this.timeoutHandler(timeoutFlag);

		console.log("realSend " + new Date().getTime(), this.sendTimer, timeoutFlag, this.index);
		if(this.deviceHandler && this.deviceHandler.sendRequest && this.requestList?.length > 0){
			let first = this.requestList.shift();
			let request = this.deviceHandler.sendRequest(first);
			console.log("first: ", first);
			console.log("request: ", request);
			if(request?.length > 0){
				this.send(request);
			}
		}
	}

	setRequestList(message){
		console.log("setRequestList: ", message);
		if(message instanceof Array){
			this.requestList = message;
		} else {
			this.requestList.push(message);
		}
		if(this.requestList?.length > 0){
			if(this.deviceHandler && this.deviceHandler.setRequestList){
				this.deviceHandler.setRequestList(this.requestList);
			}
		}
		this.realSend();
	}

    getNativeConfig() {
        return SerialPortAPI.getSerialPortConfig(this.clientRef);
    }

}

export default class SerialPorts {
    static clients = [];
	static eventHandler = null;
	static dispatchEvents(data) {
		this.clients.forEach(function(serialPort) {
			serialPort.dispatchEvent(data);
		});
	}

	static setEventHandler() {
		this.eventHandler = DeviceEventEmitter.addListener("serial_event", (data) => {
			// console.log("serial_event: ", data);
			this.dispatchEvents(data);
		});
	}

	// id: 用于标识设备，由后台传入，在mqtt消息中传回给后台，终端不适用这个字段
	// index, key: 开始用于标识设备
	// deviceType: 用于区分设备类型的，如四路调光器，智能电表等
	// address: 设备地址
	// option: 配置串口参数波特率、校验方式、开始位、数据位、停止位等，对USB转485，还有一个port参数，指明USB对应的485端口
	// interfaceType: 连接类型，如USB连接、直接485连接或模拟连接
    static async openClient(id, index, key, deivceType, address, options, interfaceType) {
		let serialOption = {
			...options,
			type: interfaceType,	
		}
		let clientRef = await SerialPortAPI.open(key, serialOption);

		var client = new SerialPortClient(options, clientRef, index, deivceType, address, id);

		/* Listen mqtt event */
		if(this.eventHandler === null) {
			this.setEventHandler();
		}
		this.clients.push(client);

		return client;
	}

    static async removeClient(client, isForce) {
        if(client) {
            await client.close(isForce);
        }
		var clientIdx = this.clients.indexOf(client);
		if (clientIdx > -1)	{
			this.clients.splice(clientIdx, 1);
		}
		if (this.clients.length > 0) {
			if (this.eventHandler !== null) {
				this.eventHandler.remove();
				this.setEventHandler();
			}
		}
	}

    static getSerialPortClients() {
        return SerialPortAPI.getSerialPortClients();
    }

	static async isSerialPortRunning(key) {
		return await SerialPortAPI.isRunning(key);
	}
}